package cn.com.blueInfo.bpm.system.repository.impl;

import cn.com.blueInfo.bpm.common.entity.BaseEntity;
import cn.com.blueInfo.bpm.common.enums.BaseDeleted;
import cn.com.blueInfo.bpm.common.repository.BaseRepository;
import cn.com.blueInfo.bpm.system.entity.Role;
import cn.com.blueInfo.bpm.system.enums.RoleType;
import cn.com.blueInfo.bpm.system.mapper.RoleMapper;
import cn.com.blueInfo.bpm.system.repository.RoleRepository;
import cn.com.blueInfo.bpm.system.request.RoleDTO;
import cn.com.blueInfo.core.entity.CurrentLoginUserInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 角色表 数据服务实现类
 * @author suxch
 * @since 2025-09-01 19:17:41
 */
@Log4j2
@Service
public class RoleRepositoryImpl
        extends ServiceImpl<RoleMapper, Role>
        implements RoleRepository, BaseRepository<Role, RoleDTO.QueryDTO> {

    @Autowired
    private CurrentLoginUserInfo currentLoginUserInfo;

    /**
     * 提供获取 CurrentLoginUserInfo 的方法（由实现类提供，避免接口中注入）
     * @return CurrentLoginUserInfo
     */
    @Override
    public CurrentLoginUserInfo getCurrentLoginUserInfo() {
        return currentLoginUserInfo;
    }

    /**
     * 新增角色
     * @param role 角色参数
     */
    @Override
    public Integer createRole(Role role) {
        return sqlExecuteResult(save(role));
    }

    /**
     * 批量新增角色
     * @param roleList 角色参数列表
     */
    @Override
    public Integer batchCreateRole(List<Role> roleList) {
        return sqlExecuteResult(saveBatch(roleList), roleList.size());
    }

    /**
     * 删除角色
     * @param roleId 角色ID
     */
    @Override
    public Integer deleteRole(Long roleId) {
        Role role = new Role();
        role.setId(roleId);
        role.setDeleted(BaseDeleted.DELETED);
        return sqlExecuteResult(removeById(role));
    }

    /**
     * 批量删除角色
     * @param roleIdList 角色ID列表
     */
    @Override
    public Integer batchDeleteRole(List<Long> roleIdList) {
        List<Role> roleList = new ArrayList<>();
        for (Long roleId : roleIdList) {
            Role role = new Role();
            role.setId(roleId);
            role.setDeleted(BaseDeleted.DELETED);
            roleList.add(role);
        }
        return sqlExecuteResult(removeBatchByIds(roleList), roleList.size());
    }

    /**
     * 更新部分角色
     * @param role 角色参数
     */
    @Override
    public Integer updateRolePartial(Role role) {
        validateUpdateId(role.getId());
        LambdaUpdateWrapper<Role> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Role::getId, role.getId());
        return sqlExecuteResult(update(updateWrapper));
    }

    /**
     * 更新全部角色
     * @param role 角色参数
     */
    @Override
    public Integer updateRole(Role role) {
        validateUpdateId(role.getId());
        return sqlExecuteResult(updateById(role));
    }

    /**
     * 查询一条角色
     * @param roleId 角色ID
     */
    @Override
    public Role getRoleById(Long roleId) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getId, roleId);
        return getOne(queryWrapper);
    }

    /**
     * 分页查询角色
     * @param roleQueryDTO 角色参数
     */
    @Override
    public Page<Role> getRolePage(RoleDTO.QueryDTO roleQueryDTO) {
        Page<Role> rolePage = new Page<>(
                roleQueryDTO.getPage(), roleQueryDTO.getSize());
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, roleQueryDTO);

        BaseDeleted deleted = roleQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeletePage(rolePage, queryWrapper);
        } else {
            return page(rolePage, queryWrapper);
        }
    }

    /**
     * 根据条件查询 角色 数量
     * @param roleQueryDTO 角色参数
     */
    @Override
    public Long getRoleCount(RoleDTO.QueryDTO roleQueryDTO) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, roleQueryDTO);

        BaseDeleted deleted = roleQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteCount(queryWrapper);
        } else {
            return count(queryWrapper);
        }
    }

    /**
     * 根据条件查询 角色
     * @param roleQueryDTO 角色参数
     */
    @Override
    public List<Role> getRoleList(RoleDTO.QueryDTO roleQueryDTO) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, roleQueryDTO);

        BaseDeleted deleted = roleQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteList(queryWrapper);
        } else {
            return list(queryWrapper);
        }
    }

    private void queryWrapper(LambdaQueryWrapper<Role> queryWrapper, RoleDTO.QueryDTO roleQueryDTO) {

        String roleCode = roleQueryDTO.getRoleCode();
        queryWrapper.eq(StringUtils.isNotBlank(roleCode), Role::getRoleCode, roleCode);

        String roleName = roleQueryDTO.getRoleName();
        queryWrapper.eq(StringUtils.isNotBlank(roleName), Role::getRoleName, roleName);

        RoleType roleType = roleQueryDTO.getRoleType();
        queryWrapper.eq(ObjectUtils.isNotEmpty(roleType), Role::getRoleType, roleType);

        String description = roleQueryDTO.getDescription();
        queryWrapper.eq(StringUtils.isNotBlank(description), Role::getDescription, description);

        addQueryWrapper(queryWrapper, roleQueryDTO, getCommonColumn());

    }

    private Map<String, SFunction<Role, ?>> getCommonColumn() {
        return BaseEntity.getCommonColumn(
                Role::getOrderNumber,
                Role::getTenantId,
                Role::getApplicationId,
                Role::getStatus,
                Role::getDeleted,
                Role::getDeleteUserId,
                Role::getDeleteTime,
                Role::getRemark,
                Role::getCreateUserId,
                Role::getCreateTime,
                Role::getUpdateUserId,
                Role::getUpdateTime,
                Role::getExtend1,
                Role::getExtend2,
                Role::getExtend3);
    }

}
